package cn.vehicle.config;

import cn.hutool.core.util.StrUtil;
import jakarta.validation.ConstraintValidator;
import jakarta.validation.ConstraintValidatorContext;


/**
 * 枚举值校验器
 * <p>
 * 用于校验字符串字段的值是否属于指定枚举类型中的有效枚举名。
 * 结合自定义注解 {@link EnumValue} 使用。
 * </p>
 *
 * <p>使用场景：</p>
 * <ul>
 *   <li>参数校验：例如校验状态字段、类型字段等必须为定义的枚举值之一；</li>
 *   <li>自动化验证：在 Spring Boot + Jakarta Validation 体系中自动生效。</li>
 * </ul>
 */
public class EnumValueValidator implements ConstraintValidator<EnumValue, String> {

    /**
     * 目标枚举类，用于校验时动态加载其枚举常量。
     */
    private Class<? extends Enum<?>> enumClass;

    /**
     * 初始化方法
     * <p>在校验器实例化时调用，从注解中获取目标枚举类。</p>
     *
     * @param constraintAnnotation 自定义注解对象，包含配置的枚举类型
     */
    @Override
    public void initialize(EnumValue constraintAnnotation) {
        this.enumClass = constraintAnnotation.enumClass();
    }

    /**
     * 校验逻辑
     * <p>判断输入的字符串是否为指定枚举类中的有效枚举名。</p>
     *
     * @param s 待校验的字符串
     * @param constraintValidatorContext 校验上下文（通常不需修改）
     * @return 若为空字符串或匹配任意枚举常量则返回 true，否则返回 false
     */
    @Override
    public boolean isValid(String s, ConstraintValidatorContext constraintValidatorContext) {
        // 若传入字符串为空，则认为校验通过（可在注解层控制是否允许为空）
        if (StrUtil.isEmpty(s)) {
            return true;
        }
        // 遍历目标枚举类的所有枚举常量
        for (Enum<?> enumConstant : enumClass.getEnumConstants()) {
            // 若输入字符串与枚举常量名匹配，校验通过
            if (enumConstant.name().equals(s)) {
                return true;
            }
        }
        // 未找到匹配的枚举常量，校验失败
        return false;
    }
}
